package com.itheima.reggie.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.reggie.common.R;
import com.itheima.reggie.dtos.SetmealDto;
import com.itheima.reggie.entity.Category;
import com.itheima.reggie.entity.Setmeal;
import com.itheima.reggie.entity.SetmealDish;
import com.itheima.reggie.ex.CustomerException;
import com.itheima.reggie.mapper.SetmealMapper;
import com.itheima.reggie.service.CategoryService;
import com.itheima.reggie.service.SetmealDishService;
import com.itheima.reggie.service.SetmealService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author ghy
 * @version v1.0
 * create on 2022/11/18 15:36
 */
@Service
@Slf4j
@Transactional
public class SetmealServiceImpl extends ServiceImpl<SetmealMapper, Setmeal> implements SetmealService {

    @Autowired
    private SetmealDishService setmealDishService;

    @Autowired
    private CategoryService categoryService;


    /**
     * 根据分类ID和状态查询
     * @param setmeal
     * @return
     */
    @Cacheable(value = "setmeal_cache", key = "#setmeal.categoryId + '_' + #setmeal.status")
    @Override
    public R findList(Setmeal setmeal) {
        LambdaQueryWrapper<Setmeal> lqw = Wrappers.<Setmeal>lambdaQuery()
                .eq(setmeal.getCategoryId() != null, Setmeal::getCategoryId, setmeal.getCategoryId())
                .eq(setmeal.getStatus() != null, Setmeal::getStatus, setmeal.getStatus())
                .orderByDesc(Setmeal::getUpdateTime);
        return R.success(this.list(lqw));
    }

    /**
     * 根据ID列表删除
     * @param ids
     * @return
     */
    //allEntries:删除setmeal_cache缓存下所有的数据
    @CacheEvict(value = "setmeal_cache", allEntries = true)
    @Override
    public R deleteByIds(List<Long> ids) {

        //判断当前套餐能否删除
        //select count(*) from setmeal where id in (?,?,?,?) and status = 1
        LambdaQueryWrapper<Setmeal> lqw = Wrappers.<Setmeal>lambdaQuery()
                .in(Setmeal::getId, ids)
                .eq(Setmeal::getStatus, 1);
        int count = this.count(lqw);
        if(count > 0) {
            //其中有套餐是售卖状态，不能删除
            throw new CustomerException("有套餐正在售卖，不能删除！！");
        }

        //1.删除套餐基本数据  setmeal
        this.removeByIds(ids);

        //2.删除套餐菜品关联数据  setmeal_dish
        //delete from setmeal_dish where setmeal_id in (?,?,?,?);
        LambdaQueryWrapper<SetmealDish> wrapper = Wrappers.<SetmealDish>lambdaQuery()
                .in(SetmealDish::getSetmealId, ids);
        setmealDishService.remove(wrapper);

        return R.success("套餐删除成功");
    }

    /**
     * 条件分页查询
     * @param page
     * @param pageSize
     * @param name
     * @return
     */
    @Override
    public R findPage(Integer page, Integer pageSize, String name) {
        //1.分页查询
        IPage<Setmeal> setmealPage = new Page<>(page, pageSize);
        LambdaQueryWrapper<Setmeal> lqw = Wrappers.<Setmeal>lambdaQuery()
                .like(StringUtils.isNotBlank(name), Setmeal::getName, name)
                .orderByDesc(Setmeal::getUpdateTime);
        this.page(setmealPage, lqw);
        //2.处理分页数据，返回给前端 Page<SetmealDto>
        IPage<SetmealDto> setmealDtoPage = new Page<>(page, pageSize);
        BeanUtils.copyProperties(setmealPage, setmealDtoPage, "records");

        List<SetmealDto> setmealDtos = setmealPage.getRecords().stream()
                .map(item -> {
                    SetmealDto setmealDto = new SetmealDto();
                    BeanUtils.copyProperties(item, setmealDto);
                    Category category = categoryService.getById(setmealDto.getCategoryId());
                    if(category != null) {
                        setmealDto.setCategoryName(category.getName());
                    }
                    return setmealDto;
                })
                .collect(Collectors.toList());
        setmealDtoPage.setRecords(setmealDtos);
        return R.success(setmealDtoPage);
    }

    /**
     * 保存套餐及关联的菜品数据
     * @param setmealDto
     * @return
     */
    //删除缓存
    @CacheEvict(value = "setmeal_cache", key = "#setmealDto.categoryId + '_' + #setmealDto.status")
    @Override
    public R addWithDishes(SetmealDto setmealDto) {
        //1.保存套餐数据
        setmealDto.setIsDeleted(0);
        this.save(setmealDto);

        //2.保存套餐跟菜品的关联数据
        List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes().stream()
                .map(item ->{
                    item.setSort(0);   //排序
                    item.setIsDeleted(0);  //是否删除
                    item.setSetmealId(setmealDto.getId());   //套餐ID
                    return item;
                }).collect(Collectors.toList());
        setmealDishService.saveBatch(setmealDishes);

        return R.success("套餐保存成功");
    }
}
